package com.egoonet.websocket;

import java.io.IOException;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.Preconditions;

public class WebSocketServer {
	private static final Logger logger = LoggerFactory.getLogger(WebSocketServer.class);
	private static final ConcurrentHashMap<MsgServerWSEndpoint, WSConnInfo> connectionList= new ConcurrentHashMap<>();
	
	public static void addConnection(MsgServerWSEndpoint endpoint){
		WSConnInfo connInfo = endpoint.getConnInfo();
		if(connInfo!=null){
			connectionList.put(endpoint, connInfo);
		}else{
			logger.warn("添加新WebSocketConnection失败，因connInfo为空");
		}
	}
	
	public static void delConnection(MsgServerWSEndpoint endpoint){
		connectionList.remove(endpoint);
	}
	
	/**
	 * 广播消息
	 * @param senderId
	 * @param msgBody
	 * @return
	 */
	public static boolean broadcast(String senderId, String msgBody){
		String msg, recvId;
		Set<MsgServerWSEndpoint> endpointSet = connectionList.keySet();
		for(MsgServerWSEndpoint endpoint: endpointSet){
			recvId = endpoint.getConnInfo().getUserId();
			if(senderId.equals(recvId)){
				continue;
			}
			
			msg = buildMsg(senderId, recvId, msgBody);
			try {
				endpoint.sendMsg(msg);
			} catch (IOException e) {
				logger.warn("广播消息发送给"+recvId+"时出现异常", e);
			}
		}

		return true;
	}
	
	public static boolean send(String senderId, String recvId, String msgBody) throws IOException{
		MsgServerWSEndpoint endpoint = getEndpointByUserId(recvId);
		Preconditions.checkNotNull(endpoint, "user not online");
		String msg = buildMsg(senderId, recvId, msgBody);
		return endpoint.sendMsg(msg);
	}
	
	private static String buildMsg(String sendid, String recvid, String msg){
		JSONObject json = new JSONObject();
		try {
			json.put("eventName", "message");
			JSONObject subData = new JSONObject();
			subData.put("reqUser", sendid);
			subData.put("resToUser", recvid);
			
			JSONObject omsg = null;
			try{
				logger.debug("待转的消息为[{}]", msg);
				omsg = new JSONObject(msg);
			}catch(Exception ex){
				logger.warn("将消息转为json出现异常", ex);
			}
			
			if(omsg != null){
				subData.put("reqMsg", omsg);
			}else{
				subData.put("reqMsg", msg);
			}
			
			
			json.put("data", subData);
		} catch (JSONException e) {
			logger.warn("在构建JSON时出现异常", e);
		}
		
		return json.toString();
	}
	
	/**
	 * 判断用户的websocket连接是否已存在
	 * @param userId
	 * @return
	 */
	public static boolean isUserExist(String userId){
		boolean isExist = false;
		MsgServerWSEndpoint endpoint = getEndpointByUserId(userId);
		if(endpoint != null){
			isExist = true;
		}
		
		return isExist;
	}
	
	/**
	 * 关闭指定用户连接
	 * @param userId
	 * @return
	 * @throws Exception 
	 */
	public static void closeUser(String userId) throws Exception{
		MsgServerWSEndpoint endpoint = getEndpointByUserId(userId);
		if(endpoint != null){
			logger.debug("开始关闭用户[{}]WebSocket连接", userId);
			try {
				endpoint.getSession().close();
			} catch (IOException e) {
				logger.warn("在关闭连接时出现异常", e);
				throw new Exception(e.getMessage());
			} finally{
				delConnection(endpoint); 
			}
		}else{
			logger.warn("关闭用户[{}]失败，因用户连接不存在");
		}
	}
	
	/**
	 * 根据用户id获取websocket连接对象
	 * @param userId
	 * @return
	 */
	public static MsgServerWSEndpoint getEndpointByUserId(String userId){
		for(Map.Entry<MsgServerWSEndpoint, WSConnInfo> entry: connectionList.entrySet()){
			if(userId.equalsIgnoreCase(entry.getValue().getUserId())){
				return entry.getKey();
			}
		}	
		
		return null;
	}
}
